Github : https://github.com/skyclad0x7b7/Pacro


 요전부터 개인적으로 사용하려고 만들다가 오픈소스로 내는것도 꽤 괜찮을 것 같다는 생각이 들어 Github에 Pacro라는 이름의 repository를 만들고 개발하기 시작했습니다. GUI 환경은 PyQt4를 이용하여 개발하였고, 자동으로 스크립트를 만들어주는 기능은 pyHook을 이용하여 구현했기 때문에 현재는 윈도우 환경만 지원합니다.


라이센스는 GNU GPL 3.0입니다.


개인적으로 개발하던 프로그램이라 로고도 아이콘도 없습니다.


현재까지는 Click과 Sleep 기능만 개발된 상태이지만 추후 다른 기능들도 추가할 예정입니다.




Pacro GUI는 이런 인터페이스로 동작하며, 반복과 가장 위 고정 기능이 있습니다.



자동으로 스크립트를 만들어주는 MakeScript는 이렇게 작동하며, Start 버튼을 누른 이후 우클릭을 할때까지의 모든 Click을 사이사이에 Sleep과 함께 저장해줍니다.

스크립트는 JSON 형식입니다.


자세한 내용은 Github를 참고하시면 되겠습니다.

'Programming' 카테고리의 다른 글

[C++] 얕은 복사, 깊은 복사, 복사 생성자  (0) 2016.12.13
[C++] std::for_each  (0) 2016.12.12
[C++] CreateMutex  (2) 2016.11.22
[PyQt4] 0x07. WebBrowser  (0) 2016.11.21
[PyQt4] 0x06. QYolk III  (0) 2016.11.18
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

[C++] CreateMutex

Programming 2016. 11. 22. 16:34



개념만 알고 있던 뮤텍스를 C++ 코드로 직접 작성하여 사용해 봤다.
뮤텍스의 개념은 정말 간단한데, 자원에 한번에 하나의 Thread나 프로세스가 접근하게 하기 위해 사용할 때 잠그고, 나올 때 풀어주며 사용하려 할 때 잠겨있으면 풀릴 때까지 기다리는 것이다.


With_Mutex.cpp

Without_Mutex.cpp


예제 소스는 위에 첨부했다.


- Without_Mutex.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <Windows.h>
 
unsigned int g_num = 0;
 
DWORD WINAPI increase_num(LPVOID max_num)
{
    for (int i = 0; i < (int)max_num; i++) {
        g_num++;
    }
    return 0;
}
 
int main(int argc, char* argv[])
{
    DWORD dThreadId;
    HANDLE hThread_1 = CreateThread(NULL0, increase_num, (LPVOID)1000000&dThreadId);
    HANDLE hThread_2 = CreateThread(NULL0, increase_num, (LPVOID)1000000&dThreadId);
    
    WaitForSingleObject(hThread_1, INFINITE);
    WaitForSingleObject(hThread_2, INFINITE);
 
    std::cout << g_num << std::endl;
    return 0;
}
 
 
cs



뮤텍스 없이 Thread 두 개를 만들어 전역변후 g_num에 1을 더하는 동작을 10만번씩 반복하게 했다.

정상적으로 돌았다면 200000이라는 결과가 나와야 하지만 결과는 다음과 같이 훨씬 작은 값이 나왔다.

동시에 한 자원에 접근했기 때문이다.




- With_Mutex.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <Windows.h>
 
unsigned int g_num = 0;
HANDLE hMutex;
 
DWORD WINAPI increase_num(LPVOID max_num)
{
    for (int i = 0; i < (int)max_num; i++) {
        WaitForSingleObject(hMutex, INFINITE);
        g_num++;
        ReleaseMutex(hMutex);
    }
    return 0;
}
 
int main(int argc, char* argv[])
{
    hMutex = CreateMutex(NULL, FALSE, NULL);
 
    DWORD dThreadId;
    HANDLE hThread_1 = CreateThread(NULL0, increase_num, (LPVOID)1000000&dThreadId);
    HANDLE hThread_2 = CreateThread(NULL0, increase_num, (LPVOID)1000000&dThreadId);
    
    WaitForSingleObject(hThread_1, INFINITE);
    WaitForSingleObject(hThread_2, INFINITE);
 
    std::cout << g_num << std::endl;
    return 0;
}
cs


이번에는 뮤텍스를 가져다가 사용해 봤다.

WaitForSingleObject에 뮤텍스를 넘기면 Release될 때까지 기다린다고 한다.

이후 작업을 수행했으면 Lock이 걸린 Mutex를 Release해준다.



정상적으로 200000이 찍히는 것을 볼 수 있다.




'Programming' 카테고리의 다른 글

[C++] std::for_each  (0) 2016.12.12
[Python] Pacro : Python 기반 매크로 프로그램  (5) 2016.11.28
[PyQt4] 0x07. WebBrowser  (0) 2016.11.21
[PyQt4] 0x06. QYolk III  (0) 2016.11.18
[PyQt4] 0x05. Final Text Editor  (0) 2016.11.17
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

오랜만에 잡담

잡담 2016. 11. 21. 17:03


블로그를 둘러보니 옛날 자료가 많다.

쓰다 만 워게임 공략(특히 LOB, Fedora4까지 다해놓고 Redhat에서 멈췄다)부터 보호 걸어둔 BoB 수업 정리내용까지...


언제 한번 정리를 하고는 싶으면서 뭔가 나름 자료는 될 것 같고, 그렇다고 워게임 공략을 이제와서 다시 작성하자니 좀 귀찮은 감도 있고...

이걸 어떻게 처리할지 약간 답답하기도 하다.


'잡담' 카테고리의 다른 글

서버를 옮겨야겠습니다  (0) 2017.01.06
피아노도 갖다뒀으니 슬슬 쳐봐야지  (0) 2016.12.20
Tistory Flatinum 스킨 수정해서 사용  (0) 2016.10.18
수습 조기종료  (0) 2016.10.04
수습기간 :D  (0) 2016.07.29
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

Qt의 WebView를 이용하여 웹 브라우저를 만들어 보았다.

주소창과 뒤로, 앞으로 버튼, 새로 고침과 중지 버튼이 있으며 따로 브라우저 창의 투명도를 조절할 수 있는 가로 슬라이더도 추가했다.

setWindowOpacity(value) 함수로 윈도우 창의 투명도를 조절할 수 있으며, value의 타입은 0~1 사이의 float이다.



실행 후 네이버에 접속한 모습이다.



네이버에 접속 후 투명도를 낮춘 모습이다.


  [ Source ]


- Main.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# -*- coding: utf-8 -*-
 
# Form implementation generated from reading ui file 'Main.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
 
from PyQt4 import QtCore, QtGui
 
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s
 
try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)
 
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(593395)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.webView = QtWebKit.QWebView(self.centralwidget)
        self.webView.setGeometry(QtCore.QRect(040591331))
        self.webView.setUrl(QtCore.QUrl(_fromUtf8("about:blank")))
        self.webView.setObjectName(_fromUtf8("webView"))
        self.horizontalLayoutWidget = QtGui.QWidget(self.centralwidget)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(0059141))
        self.horizontalLayoutWidget.setObjectName(_fromUtf8("horizontalLayoutWidget"))
        self.horizontalLayout = QtGui.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
        self.button_prev = QtGui.QPushButton(self.horizontalLayoutWidget)
        self.button_prev.setObjectName(_fromUtf8("button_prev"))
        self.horizontalLayout.addWidget(self.button_prev)
        self.button_stop = QtGui.QPushButton(self.horizontalLayoutWidget)
        self.button_stop.setObjectName(_fromUtf8("button_stop"))
        self.horizontalLayout.addWidget(self.button_stop)
        self.button_reload = QtGui.QPushButton(self.horizontalLayoutWidget)
        self.button_reload.setObjectName(_fromUtf8("button_reload"))
        self.horizontalLayout.addWidget(self.button_reload)
        self.button_next = QtGui.QPushButton(self.horizontalLayoutWidget)
        self.button_next.setObjectName(_fromUtf8("button_next"))
        self.horizontalLayout.addWidget(self.button_next)
        self.lineEdit_url = QtGui.QLineEdit(self.horizontalLayoutWidget)
        self.lineEdit_url.setObjectName(_fromUtf8("lineEdit_url"))
        self.horizontalLayout.addWidget(self.lineEdit_url)
        self.horizontalSlider_opacity = QtGui.QSlider(self.horizontalLayoutWidget)
        self.horizontalSlider_opacity.setMaximum(99)
        self.horizontalSlider_opacity.setSliderPosition(99)
        self.horizontalSlider_opacity.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider_opacity.setObjectName(_fromUtf8("horizontalSlider_opacity"))
        self.horizontalLayout.addWidget(self.horizontalSlider_opacity)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0059321))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)
 
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
 
    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow""WebBrowser", None))
        self.button_prev.setText(_translate("MainWindow""<", None))
        self.button_stop.setText(_translate("MainWindow""Stop", None))
        self.button_reload.setText(_translate("MainWindow""Reload", None))
        self.button_next.setText(_translate("MainWindow"">", None))
 
from PyQt4 import QtWebKit
 
cs


- Start.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import sys
from Main import Ui_MainWindow
from PyQt4 import QtCore, QtGui, QtWebKit
 
class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.start_page = "about:blank"
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.initialize()
        self.ui.webView.page().setLinkDelegationPolicy(QtWebKit.QWebPage.DelegateAllLinks)
 
        QtCore.QObject.connect(self.ui.lineEdit_url, QtCore.SIGNAL("returnPressed()"), self.url_changed)
        QtCore.QObject.connect(self.ui.button_reload, QtCore.SIGNAL("clicked()"), self.reload_clicked)
        QtCore.QObject.connect(self.ui.button_prev, QtCore.SIGNAL("clicked()"), self.prev_clicked)
        QtCore.QObject.connect(self.ui.button_next, QtCore.SIGNAL("clicked()"), self.next_clicked)
        QtCore.QObject.connect(self.ui.button_stop, QtCore.SIGNAL("clicked()"), self.stop_clicked)
        QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("linkClicked (const QUrl&)"), self.link_clicked)
        QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("loadProgress (int)"), self.load_progress)
        QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("titleChanged (const QString&)"), self.title_changed)
        QtCore.QObject.connect(self.ui.horizontalSlider_opacity, QtCore.SIGNAL("sliderMoved(int)"), self.opacity_changed)
 
    def stop_clicked(self):
        self.ui.webView.stop()
 
    def reload_clicked(self):
        self.ui.webView.setUrl(QtCore.QUrl(self.ui.lineEdit_url.text()))
 
    def prev_clicked(self):
        page = self.ui.webView.page()
        history = page.history()
        history.back()
        if history.canGoBack():
            self.ui.button_prev.setEnabled(True)
        else:
            self.ui.button_prev.setEnabled(False)
 
        self.ui.button_next.setEnabled(True)
 
 
    def next_clicked(self):
        page = self.ui.webView.page()
        history = page.history()
        history.forward()
        if history.canGoForward():
            self.ui.button_next.setEnabled(True)
        else:
            self.ui.button_next.setEnabled(False)
 
        self.ui.button_prev.setEnabled(True)
 
    def url_changed(self):
        # url changed by user
        curr_page = self.ui.webView.page()
        history = curr_page.history()
        if history.canGoBack():
            self.ui.button_prev.setEnabled(True)
        else:
            self.ui.button_prev.setEnabled(False)
 
        if history.canGoForward():
            self.ui.button_next.setEnabled(True)
        else:
            self.ui.button_next.setEnabled(False)
 
        self.ui.button_reload.setEnabled(True)
        url = self.ui.lineEdit_url.text()
        self.ui.webView.setUrl(QtCore.QUrl(url))
 
    def link_clicked(self, url):
        # link clicked
        curr_page = self.ui.webView.page()
        history = curr_page.history()
        if history.canGoBack():
            self.ui.button_prev.setEnabled(True)
        else:
            self.ui.button_prev.setEnabled(False)
 
        if history.canGoForward():
            self.ui.button_next.setEnabled(True)
        else:
            self.ui.button_next.setEnabled(False)
 
        self.ui.button_reload.setEnabled(True)
        self.ui.lineEdit_url.setText(url.toString())
        self.reload_clicked()
 
    def load_progress(self, load):
        if load == 100:
            self.ui.button_stop.setEnabled(False)
        else:
            self.ui.button_stop.setEnabled(True)
 
    def title_changed(self, title):
        self.setWindowTitle(title)
 
    def opacity_changed(self, value):
        self.setWindowOpacity((value + 1)/100.0)
 
 
    def initialize(self):
        self.ui.button_prev.setEnabled(False)
        self.ui.button_next.setEnabled(False)
        self.ui.button_stop.setEnabled(False)
        self.ui.button_reload.setEnabled(False)
        self.ui.lineEdit_url.setText(self.start_page)
        self.ui.webView.setUrl(QtCore.QUrl(self.start_page))
 
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = StartQT4()
    myapp.show()
    sys.exit(app.exec_())
cs


github : https://github.com/skyclad0x7b7/StudyPyQt4/tree/master/0x07.%20WebBrowser





'Programming' 카테고리의 다른 글

[Python] Pacro : Python 기반 매크로 프로그램  (5) 2016.11.28
[C++] CreateMutex  (2) 2016.11.22
[PyQt4] 0x06. QYolk III  (0) 2016.11.18
[PyQt4] 0x05. Final Text Editor  (0) 2016.11.17
[PyQt4] 0x04. QYolk II  (0) 2016.11.16
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,



 기본적으로 CPU는 하나당 한 가지의 일밖에 동시에 처리할 수 없다.

때문에 메모리에 두 개 이상의 프로그램을 배치했다고 하더라도 두 개의 프로그램이 동시에 실행될 수는 없다.


 결국 멀티 태스킹을 구현하기 위해서는 아주 짧은 시간동안 한 프로세스를 실행하다가 다른 프로세스로 CPU를 사용할 수 있도록 넘겨주는 것을 반복해야 한다. 이를 간단하게 구현하기 위해서는 각 어플리케이션마다 중간에 '전환점'을 만들어 두면 된다. 전환점은 '내 처리를 잠시 멈추고 CPU를 다른 프로세스에게 배정할 적당한 때가 왔다'라는 것을 알리는 것으로, OS에게 특정 System Call을 호출하여 다른 프로세스에게 CPU를 배정하는 일을 하게 만든다. 이렇게 OS가 각 애플리케이션의 처리를 나눠서 조금씩 실행시키는 기능을 '디스패치(Dispatch)'라고 부른다.


 하지만 이런 방식으로 CPU를 나눠 쓰며 멀티태스킹을 구현하게 되면 문제가 생긴다.

'전환점'은 어플리케이션이 직접 호출하는 것이므로 어플리케이션 설계 단계에서 어디가 전환점인지를 알아야 한다. 다시 말해서 CPU 배분이라는 OS 고유의 권한을 어플리케이션 설계자에게 전가할 수밖에 없다는 것이다. 또한 '전환점'을 사용하게 되면 이 '전환점'이 호출되기 전에는 절대로 다른 프로세스에게 CPU가 배분되지 않는다는 문제도 발생한다. 따라서 다른 방법을 사용해서 멀티태스킹을 구현할 필요가 있게 되는데, 이후에는 따로 '전환점'의 System Call을 사용하지 않고 어떤 것이든 System Call을 사용한다면 즉시 Dispatch가 일어나도록 했다.


 하지만 이 방식에도 문제가 많다.

시스템 콜을 잘 사용하지 않고 연산만을 많이 수행하는 프로그램이나 소프트웨어상의 결함으로 무한 루프에 빠져버려 시스템 콜을 호출하지 않는 프로세스가 있다고 가정하면 다른 프로세스는 CPU를 할당받을 수가 없게 된다. 이를 방지하기 위해 최종적으로 CPU는 타이머와 끼어들기(interrupt)를 이용한 멀티 태스킹을 구현했다. 끼어들기는 CPU가 어떤 작업을 진행하고 있어도 이것을 강제로 중단시키고 OS로 돌아와 다른 프로세스에게 CPU를 할당할 수 있도록 하는 신호를 의미한다.


OS는 어플리케이션으로 CPU 제어를 넘기기 전에 항상 타이머를 설정하여 일정 시간 이후 끼어들기가 발생하도록 한다.

그러면 어플리케이션으로 제어가 넘어간 후에 무한 루프나 긴 연산으로 System Call이 발생하지 않더라도 일정 시간 후에는 강제적으로 OS로 제어를 되돌릴 수 있다.


 이렇게 타이머 끼어들기를 사용하는 프로그램 전환 방법을 시간을 짧게 구분해서 애플리케이션끼리 서로 나눈다고 하여 '시분할 시스템'이라고 한다. 앞에서 언급한 시스템 호출을 계기로 CPU를 재배정하는 방식의 멀티 태스킹은 다른 타 어플리케이션의 존재를 의식하고 계속 System Call을 호출해주지 않으면 작동할 수 없기 때문에 '협조적 멀티태스킹'이라고 부르며, 시분할 시스템처럼 타 어플리케이션의 중단을 기다릴 필요가 없는 멀티태스킹 방식을 '비협조적 멀티태스킹'이라고 부른다. 또한 이런 '비협조적 멀티태스킹'은 다른 어플리케이션의 중단을 기다리지 않고도 처리를 가로챌 수 있다는 점에서, 즉 '먼저 취할 수 있다'는 점에서 '선점 멀티태스킹(Preemptive multitasking)'이라고도 하며, 그 반대로 다른 어플리케이션의 처리를 먼저 취할 수 없는 멀티태스킹을 '비선점 멀티태스킹'이라고 한다.

'Knowledge' 카테고리의 다른 글

Memory Segmentation  (0) 2016.12.27
NAT와 NAPT의 개념과 원리  (10) 2016.12.01
PCB (Process Control Block)  (0) 2016.11.14
[Assembly] Intel x86, Local JMP [0xE9]  (0) 2016.11.07
[BigData] Spark 공부  (0) 2016.10.19
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

[PyQt4] 0x06. QYolk III

Programming 2016. 11. 18. 15:48


http://5kyc1ad.tistory.com/246 에서 만든 QYolk II에 기능을 조금 추가했다.

업데이트 탭을 추가하고 최신 버전이 아닌 패키지가 있을 경우 표시하고 몇 버전으로 업그레이드가 가능한지를 나타내었다.


  [ Source ]


- Main.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# -*- coding: utf-8 -*-
 
# Form implementation generated from reading ui file 'Main.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
 
from PyQt4 import QtCore, QtGui
 
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s
 
try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)
 
class Ui_QYolk(object):
    def setupUi(self, QYolk):
        QYolk.setObjectName(_fromUtf8("QYolk"))
        QYolk.resize(565345)
        self.centralwidget = QtGui.QWidget(QYolk)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.tab_widget = QtGui.QTabWidget(self.centralwidget)
        self.tab_widget.setGeometry(QtCore.QRect(100551291))
        self.tab_widget.setObjectName(_fromUtf8("tab_widget"))
        self.tab_all_packages = QtGui.QWidget()
        self.tab_all_packages.setObjectName(_fromUtf8("tab_all_packages"))
        self.all_list = QtGui.QTreeWidget(self.tab_all_packages)
        self.all_list.setGeometry(QtCore.QRect(00541261))
        self.all_list.setObjectName(_fromUtf8("all_list"))
        self.tab_widget.addTab(self.tab_all_packages, _fromUtf8(""))
        self.tab_active = QtGui.QWidget()
        self.tab_active.setObjectName(_fromUtf8("tab_active"))
        self.active_list = QtGui.QTreeWidget(self.tab_active)
        self.active_list.setGeometry(QtCore.QRect(00541261))
        self.active_list.setObjectName(_fromUtf8("active_list"))
        self.tab_widget.addTab(self.tab_active, _fromUtf8(""))
        self.tab_not_active = QtGui.QWidget()
        self.tab_not_active.setObjectName(_fromUtf8("tab_not_active"))
        self.not_active_list = QtGui.QTreeWidget(self.tab_not_active)
        self.not_active_list.setGeometry(QtCore.QRect(00541261))
        self.not_active_list.setObjectName(_fromUtf8("not_active_list"))
        self.tab_widget.addTab(self.tab_not_active, _fromUtf8(""))
        self.tab_update = QtGui.QWidget()
        self.tab_update.setObjectName(_fromUtf8("tab_update"))
        self.update_list = QtGui.QTreeWidget(self.tab_update)
        self.update_list.setGeometry(QtCore.QRect(00551271))
        self.update_list.setObjectName(_fromUtf8("update_list"))
        self.tab_widget.addTab(self.tab_update, _fromUtf8(""))
        self.info_label = QtGui.QLabel(self.centralwidget)
        self.info_label.setGeometry(QtCore.QRect(1028554131))
        self.info_label.setObjectName(_fromUtf8("info_label"))
        QYolk.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(QYolk)
        self.menubar.setGeometry(QtCore.QRect(0056521))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        QYolk.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(QYolk)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        QYolk.setStatusBar(self.statusbar)
 
        self.retranslateUi(QYolk)
        self.tab_widget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(QYolk)
 
    def retranslateUi(self, QYolk):
        QYolk.setWindowTitle(_translate("QYolk""QYolk III", None))
        self.all_list.headerItem().setText(0, _translate("QYolk""Package Name", None))
        self.all_list.headerItem().setText(1, _translate("QYolk""Version", None))
        self.all_list.headerItem().setText(2, _translate("QYolk""Status", None))
        self.tab_widget.setTabText(self.tab_widget.indexOf(self.tab_all_packages), _translate("QYolk""All Packages", None))
        self.active_list.headerItem().setText(0, _translate("QYolk""Package Name", None))
        self.active_list.headerItem().setText(1, _translate("QYolk""Version", None))
        self.active_list.headerItem().setText(2, _translate("QYolk""Status", None))
        self.tab_widget.setTabText(self.tab_widget.indexOf(self.tab_active), _translate("QYolk""Active", None))
        self.not_active_list.headerItem().setText(0, _translate("QYolk""Package Name", None))
        self.not_active_list.headerItem().setText(1, _translate("QYolk""Version", None))
        self.not_active_list.headerItem().setText(2, _translate("QYolk""Status", None))
        self.tab_widget.setTabText(self.tab_widget.indexOf(self.tab_not_active), _translate("QYolk""Not Active", None))
        self.update_list.headerItem().setText(0, _translate("QYolk""Package Name", None))
        self.update_list.headerItem().setText(1, _translate("QYolk""Installed Version", None))
        self.update_list.headerItem().setText(2, _translate("QYolk""Available Version", None))
        self.tab_widget.setTabText(self.tab_widget.indexOf(self.tab_update), _translate("QYolk""Updates", None))
        self.info_label.setText(_translate("QYolk""TextLabel", None))
 
 
cs


- Start.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import sys
from Main import Ui_QYolk
from PyQt4 import QtCore, QtGui
from yolk import yolklib
from os.path import expanduser
from yolk.cli import get_pkglist
from yolk.yolklib import get_highest_version, get_distributions, get_highest_installed
from yolk.pypi import CheeseShop
import pkg_resources
from os.path import isfile
from datetime import timedelta
from datetime import datetime
 
class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_QYolk()
        self.ui.setupUi(self)
        self.ui.info_label.setText("")
 
        # set Column Width
        self.ui.all_list.setColumnWidth(0200)
        self.ui.all_list.setColumnWidth(1200)
        self.ui.active_list.setColumnWidth(0200)
        self.ui.active_list.setColumnWidth(1200)
        self.ui.not_active_list.setColumnWidth(0200)
        self.ui.not_active_list.setColumnWidth(1200)
        self.ui.update_list.setColumnWidth(0200)
        self.ui.update_list.setColumnWidth(1200)
 
        QtCore.QObject.connect(self.ui.tab_widget, QtCore.SIGNAL("currentChanged(int)"), self.tab_changed)
 
        packages = get_distributions('all')
        for pkg in packages:
            newItem = QtGui.QTreeWidgetItem(self.ui.all_list)
            pk = str(pkg[0]).split(' ')
            if pkg[1]:
                status = 'Active'
            else:
                status = 'Not Active'
                newItem.setTextColor(0, QtGui.QColor(128128128))
                newItem.setTextColor(1, QtGui.QColor(128128128))
                newItem.setTextColor(2, QtGui.QColor(128128128))
                
            newItem.setText(0, pk[0])
            newItem.setText(1, pk[1])
            newItem.setText(2, status)
 
        for pkg in get_distributions('active'):
            newItem = QtGui.QTreeWidgetItem(self.ui.active_list)
            pk = str(pkg[0]).split(' ')
            newItem.setText(0, pk[0])
            newItem.setText(1, pk[1])
            newItem.setText(2'Active')
 
        for pkg in get_distributions('nonactive'):
            newItem = QtGui.QTreeWidgetItem(self.ui.not_active_list)
            pk = str(pkg[0]).split(' ')
            newItem.setText(0, pk[0])
            newItem.setText(1, pk[1])
            newItem.setText(2'Not Active')
 
    def tab_changed(self, column):
        if column == 0:
            message = "<b>QYolk</b> : Browsing all installed cheeseshop packages"
        elif column == 1:
            message = "<b>QYolk</b> : Browsing active packages"
        elif column == 2:
            message = "<b>QYolk</b> : Browsing not active packages (older versions)"
        elif column == 3:
            message = "<b>QYolk</b> : Browsing available updates"
            for pkg in get_fresh_updates():
                newItem = QtGui.QTreeWidgetItem(self.ui.update_list)
                newItem.setText(0, pkg[0])
                newItem.setText(1, pkg[1])
                newItem.setText(2, pkg[2])
 
        self.ui.info_label.setText(message)
 
        
 
def get_fresh_updates(package_name = "", version = ""):
    ret = []
    pypi = CheeseShop()
    for pkg in get_pkglist():
        for (dist, active) in get_distributions("all", pkg, get_highest_installed(pkg)):
            (project_name, versions) = pypi.query_versions_pypi(dist.project_name)
            if versions:
                newest = get_highest_version(versions)
                if newest != dist.version:
                    if pkg_resources.parse_version(dist.version) < pkg_resources.parse_version(newest):
                        ret.append([project_name, dist.version, newest])
 
    return ret
 
 
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = StartQT4()
    myapp.show()
    sys.exit(app.exec_())
cs


github : https://github.com/skyclad0x7b7/StudyPyQt4/tree/master/0x06.%20QYolk%20III

'Programming' 카테고리의 다른 글

[C++] CreateMutex  (2) 2016.11.22
[PyQt4] 0x07. WebBrowser  (0) 2016.11.21
[PyQt4] 0x05. Final Text Editor  (0) 2016.11.17
[PyQt4] 0x04. QYolk II  (0) 2016.11.16
[PyQt4] 0x03. QYolk I  (6) 2016.11.15
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

0x02. Extended Text Editor에서 만들었던 텍스트 에디터에 기능을 더 추가하여 만들었다.

수정 중인 파일을 다른 프로세스에서 수정하거나 삭제했을 경우, 그것을 감지하여 다시 로드할지, 덮어쓸지를 정할 수 있다.

File Save할 때도 파일 다이얼로그를 열어 저장할 위치를 선택 가능하게 하였다.


UI는 Window Title을 'Final Text Editor'로 바꾼 것 외에는 변한 게 없고 Start.py의 내부 코드만 좀 추가되었다.




  [ Source ]


- Main.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# -*- coding: utf-8 -*-
 
# Form implementation generated from reading ui file 'Main.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
 
from PyQt4 import QtCore, QtGui
 
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s
 
try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)
 
class Ui_notepad(object):
    def setupUi(self, notepad):
        notepad.setObjectName(_fromUtf8("notepad"))
        notepad.resize(802625)
        self.centralwidget = QtGui.QWidget(notepad)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.textBrowser = QtGui.QTextBrowser(self.centralwidget)
        self.textBrowser.setGeometry(QtCore.QRect(1040781541))
        self.textBrowser.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByKeyboard|QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextBrowserInteraction|QtCore.Qt.TextEditable|QtCore.Qt.TextEditorInteraction|QtCore.Qt.TextSelectableByKeyboard|QtCore.Qt.TextSelectableByMouse)
        self.textBrowser.setObjectName(_fromUtf8("textBrowser"))
        self.button_open = QtGui.QPushButton(self.centralwidget)
        self.button_open.setGeometry(QtCore.QRect(10107523))
        self.button_open.setObjectName(_fromUtf8("button_open"))
        self.button_save = QtGui.QPushButton(self.centralwidget)
        self.button_save.setGeometry(QtCore.QRect(90107523))
        self.button_save.setCheckable(False)
        self.button_save.setAutoDefault(False)
        self.button_save.setDefault(False)
        self.button_save.setFlat(False)
        self.button_save.setObjectName(_fromUtf8("button_save"))
        self.button_close = QtGui.QPushButton(self.centralwidget)
        self.button_close.setGeometry(QtCore.QRect(710107523))
        self.button_close.setObjectName(_fromUtf8("button_close"))
        notepad.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(notepad)
        self.menubar.setGeometry(QtCore.QRect(0080221))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        notepad.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(notepad)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        notepad.setStatusBar(self.statusbar)
 
        self.retranslateUi(notepad)
        QtCore.QMetaObject.connectSlotsByName(notepad)
 
    def retranslateUi(self, notepad):
        notepad.setWindowTitle(_translate("notepad""Final Text Editor", None))
        self.button_open.setText(_translate("notepad""Open", None))
        self.button_save.setText(_translate("notepad""Save", None))
        self.button_close.setText(_translate("notepad""Close", None))
 
 
cs


- Start.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import sys
import codecs
from os.path import isfile
from PyQt4 import QtCore, QtGui
from Main import Ui_notepad
 
class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_notepad()
        self.ui.setupUi(self)
        self.watcher = QtCore.QFileSystemWatcher(self)
 
        QtCore.QObject.connect(self.ui.button_open, QtCore.SIGNAL("clicked()"), self.file_dialog)
        QtCore.QObject.connect(self.ui.button_save, QtCore.SIGNAL("clicked()"), self.file_save)
        QtCore.QObject.connect(self.ui.textBrowser, QtCore.SIGNAL("textChanged()"), self.enable_save)
        QtCore.QObject.connect(self.ui.button_close, QtCore.SIGNAL("clicked()"), self.file_close)
        QtCore.QObject.connect(self.watcher, QtCore.SIGNAL("fileChanged(const QString&)"), self.file_changed)
        self.initalize()
 
    def initalize(self):
        self.ui.textBrowser.setPlainText("")
        self.ui.button_save.setEnabled(False)
        self.setWindowTitle("Final Text Editor")
        self.filename = ""
 
    def file_dialog(self):
        fd = QtGui.QFileDialog(self)
        newFile = fd.getOpenFileName()
        if isfile(newFile) and self.filename != newFile:
            s = codecs.open(newFile, 'r''utf-8').read()
            self.ui.textBrowser.setPlainText(s)
            self.setWindowTitle(newFile)
            self.ui.button_save.setEnabled(False)
            if self.filename != "":
                self.watcher.removePath(self.filename)
            self.watcher.addPath(newFile)
            self.filename = newFile
 
    def enable_save(self):
        self.ui.button_save.setEnabled(True)
 
    def file_save(self):
        if self.filename != "" and isfile(self.filename): # File Opened and exists
            file = codecs.open(self.filename, 'w''utf-8')
            file.write(unicode(self.ui.textBrowser.toPlainText()))
            file.close()
            self.ui.button_save.setEnabled(False)
        else# File not opened or not exists
            fd = QtGui.QFileDialog(self)
            newFile = fd.getSaveFileName()
            if newFile:
                s = codecs.open(newFile, 'w''utf-8')
                s.write(unicode(self.ui.textBrowser.toPlainText()))
                s.close();
                self.ui.button_save.setEnabled(False)
 
 
    def file_close(self):
        if isfile(self.filename):
            # not saved
            if self.ui.button_save.isEnabled():
                message = QtGui.QMessageBox(self)
                message.setText('Would you like to save the file before closing?')
                message.setWindowTitle("Warning")
                message.setIcon(QtGui.QMessageBox.Question)
                message.addButton('Save', QtGui.QMessageBox.AcceptRole)
                message.addButton('Discard', QtGui.QMessageBox.DestructiveRole)
                message.addButton('Cancel', QtGui.QMessageBox.RejectRole)
                message.setDetailedText('Unsaved changes in file: ' + str(self.filename))
                message.exec_()
                response = message.clickedButton().text()
                if response == 'Save':
                    self.file_save()
                    self.ui.button_save.setEnabled(False)
                elif response == 'Discard':
                    self.initalize()
                else:
                    pass
            else:
                self.initalize()
 
    def file_changed(self, path):
        response = False
 
        # Button texts
        SAVE     = 'Save AS'
        RELOAD     = 'Reload File'
        CANCEL     = 'Cancel'
        message = QtGui.QMessageBox(self)
        message.setText('Opened file have been changed!')
        message.setWindowTitle('Final Text Editor')
        message.setIcon(QtGui.QMessageBox.Warning)
        message.addButton(SAVE, QtGui.QMessageBox.AcceptRole)
        message.addButton(RELOAD, QtGui.QMessageBox.DestructiveRole)
        message.addButton(CANCEL, QtGui.QMessageBox.RejectRole)
        message.setDetailedText('The File "{0}" have been changed or removed by other application. What do you want to do?'.format(self.filename))
        message.exec_()
        response = message.clickedButton().text()
        # Save Current File to new
        if response == SAVE:
            fd = QtGui.QFileDialog(self)
            newFile = fd.getSaveFileName()
            if newFile:
                s = codecs.open(newFile, 'w''utf-8')
                s.write(unicode(self.ui.textBrowser.toPlainText()))
                s.close()
                self.ui.button_save.setEnabled(False)
                # new file, remove old and add the new one to the watcher
                if self.filename and str(newFile) != str(self.filename):
                    self.watcher.removePath(self.filename)
                    self.watcher.addPath(newFile)
                    self.filename = newFile
        # reload the text in the editor
        elif response == RELOAD:
            s = codecs.open(self.filename, 'r''utf-8').read()
            self.ui.textBrowser.setPlainText(s)
            self.ui.button_save.setEnabled(False)
 
 
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = StartQT4()
    myapp.show()
    sys.exit(app.exec_())
cs


github : https://github.com/skyclad0x7b7/StudyPyQt4/tree/master/0x05.%20Final%20Text%20Editor

'Programming' 카테고리의 다른 글

[PyQt4] 0x07. WebBrowser  (0) 2016.11.21
[PyQt4] 0x06. QYolk III  (0) 2016.11.18
[PyQt4] 0x04. QYolk II  (0) 2016.11.16
[PyQt4] 0x03. QYolk I  (6) 2016.11.15
[PyQt4] 0x02. Extended Text Editor  (0) 2016.11.15
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

[PyQt4] 0x04. QYolk II

Programming 2016. 11. 16. 10:17

이전에 짰던 QYolk에 탭을 추가하여 Active상태인 것과 Not Active 상태인 것을 나눠서 볼 수 있게 하였다.

밑에 Label도 추가하여 탭을 변경 시 해당 탭에 대한 설명이 간략하게 나타나도록 설정하였다.



++ 2016.11.18

- Yolk 라이브러리를 https://pypi.python.org/pypi/yolk3k 로 업데이트하면서 함수를 일부 변경하였습니다. 

- ui에서 Version을 Package name이라고 잘못 작성하여 수정하였습니다.






 [ Source ]


- Main.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# -*- coding: utf-8 -*-
 
# Form implementation generated from reading ui file 'Main.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
 
from PyQt4 import QtCore, QtGui
 
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s
 
try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)
 
class Ui_QYolk(object):
    def setupUi(self, QYolk):
        QYolk.setObjectName(_fromUtf8("QYolk"))
        QYolk.resize(565345)
        self.centralwidget = QtGui.QWidget(QYolk)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.tab_widget = QtGui.QTabWidget(self.centralwidget)
        self.tab_widget.setGeometry(QtCore.QRect(100551291))
        self.tab_widget.setObjectName(_fromUtf8("tab_widget"))
        self.tab_all_packages = QtGui.QWidget()
        self.tab_all_packages.setObjectName(_fromUtf8("tab_all_packages"))
        self.all_list = QtGui.QTreeWidget(self.tab_all_packages)
        self.all_list.setGeometry(QtCore.QRect(00541261))
        self.all_list.setObjectName(_fromUtf8("all_list"))
        self.tab_widget.addTab(self.tab_all_packages, _fromUtf8(""))
        self.tab_active = QtGui.QWidget()
        self.tab_active.setObjectName(_fromUtf8("tab_active"))
        self.active_list = QtGui.QTreeWidget(self.tab_active)
        self.active_list.setGeometry(QtCore.QRect(00541261))
        self.active_list.setObjectName(_fromUtf8("active_list"))
        self.tab_widget.addTab(self.tab_active, _fromUtf8(""))
        self.tab_not_active = QtGui.QWidget()
        self.tab_not_active.setObjectName(_fromUtf8("tab_not_active"))
        self.not_active_list = QtGui.QTreeWidget(self.tab_not_active)
        self.not_active_list.setGeometry(QtCore.QRect(00541261))
        self.not_active_list.setObjectName(_fromUtf8("not_active_list"))
        self.tab_widget.addTab(self.tab_not_active, _fromUtf8(""))
        self.info_label = QtGui.QLabel(self.centralwidget)
        self.info_label.setGeometry(QtCore.QRect(1028554131))
        self.info_label.setObjectName(_fromUtf8("info_label"))
        QYolk.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(QYolk)
        self.menubar.setGeometry(QtCore.QRect(0056521))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        QYolk.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(QYolk)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        QYolk.setStatusBar(self.statusbar)
 
        self.retranslateUi(QYolk)
        self.tab_widget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(QYolk)
 
    def retranslateUi(self, QYolk):
        QYolk.setWindowTitle(_translate("QYolk""QYolk II", None))
        self.all_list.headerItem().setText(0, _translate("QYolk""Package Name", None))
        self.all_list.headerItem().setText(1, _translate("QYolk""Version", None))
        self.all_list.headerItem().setText(2, _translate("QYolk""Status", None))
        self.tab_widget.setTabText(self.tab_widget.indexOf(self.tab_all_packages), _translate("QYolk""All Packages", None))
        self.active_list.headerItem().setText(0, _translate("QYolk""Package Name", None))
        self.active_list.headerItem().setText(1, _translate("QYolk""Version", None))
        self.active_list.headerItem().setText(2, _translate("QYolk""Status", None))
        self.tab_widget.setTabText(self.tab_widget.indexOf(self.tab_active), _translate("QYolk""Active", None))
        self.not_active_list.headerItem().setText(0, _translate("QYolk""Package Name", None))
        self.not_active_list.headerItem().setText(1, _translate("QYolk""Version", None))
        self.not_active_list.headerItem().setText(2, _translate("QYolk""Status", None))
        self.tab_widget.setTabText(self.tab_widget.indexOf(self.tab_not_active), _translate("QYolk""Not Active", None))
        self.info_label.setText(_translate("QYolk""TextLabel", None))
 
 
cs


- Start.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import sys
from PyQt4 import QtCore, QtGui
from Main import Ui_QYolk
from yolk import yolklib
 
class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_QYolk()
        self.ui.setupUi(self)
        self.ui.info_label.setText("")
 
        # set Column Width
        self.ui.all_list.setColumnWidth(0200)
        self.ui.all_list.setColumnWidth(1200)
        self.ui.active_list.setColumnWidth(0200)
        self.ui.active_list.setColumnWidth(1200)
        self.ui.not_active_list.setColumnWidth(0200)
        self.ui.not_active_list.setColumnWidth(1200)
 
        QtCore.QObject.connect(self.ui.tab_widget, QtCore.SIGNAL("currentChanged(int)"), self.tab_changed)
 
        packages = yolklib.get_distributions('all')
        for pkg in packages:
            newItem = QtGui.QTreeWidgetItem(self.ui.all_list)
            pk = str(pkg[0]).split(' ')
            if pkg[1]:
                status = 'Active'
            else:
                status = 'Not Active'
                newItem.setTextColor(0, QtGui.QColor(128128128))
                newItem.setTextColor(1, QtGui.QColor(128128128))
                newItem.setTextColor(2, QtGui.QColor(128128128))
                
            newItem.setText(0, pk[0])
            newItem.setText(1, pk[1])
            newItem.setText(2, status)
 
        for pkg in yolklib.get_distributions('active'):
            newItem = QtGui.QTreeWidgetItem(self.ui.active_list)
            pk = str(pkg[0]).split(' ')
            newItem.setText(0, pk[0])
            newItem.setText(1, pk[1])
            newItem.setText(2'Active')
 
        for pkg in yolklib.get_distributions('nonactive'):
            newItem = QtGui.QTreeWidgetItem(self.ui.not_active_list)
            pk = str(pkg[0]).split(' ')
            newItem.setText(0, pk[0])
            newItem.setText(1, pk[1])
            newItem.setText(2'Not Active')
 
    def tab_changed(self, column):
        if column == 0:
            message = "<b>QYolk</b> : Browsing all installed cheeseshop packages"
        elif column == 1:
            message = "<b>QYolk</b> : Browsing active packages"
        elif column == 2:
            message = "<b>QYolk</b> : Browsing not active packages (older versions)"
 
        self.ui.info_label.setText(message)
 
 
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = StartQT4()
    myapp.show()
    sys.exit(app.exec_())
cs


github : https://github.com/skyclad0x7b7/StudyPyQt4/tree/master/0x04.%20QYolk%20II

'Programming' 카테고리의 다른 글

[PyQt4] 0x06. QYolk III  (0) 2016.11.18
[PyQt4] 0x05. Final Text Editor  (0) 2016.11.17
[PyQt4] 0x03. QYolk I  (6) 2016.11.15
[PyQt4] 0x02. Extended Text Editor  (0) 2016.11.15
[PyQt4] 0x01. PyQt4 설치, Simple text editor  (0) 2016.11.15
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

[PyQt4] 0x03. QYolk I

Programming 2016. 11. 15. 14:42

Python package 중에는 Yolk라고 하는 것이 있다.

이 사이트에 설명이 되어 있는데

자신의 시스템에 설치된 PyPI(Python Package Index)를 관리할 수 있는 툴이다.




보다시피 커맨드라인 기반 툴이기 때문에 GUI로는 볼 수 없는데, 이를 Qt로 GUI화한 것이 QYolk이다.

사실 이미 만들어져 있는 툴이기는 하다. (https://www.linux-apps.com/content/show.php/QYolk?content=107046)


처음엔 일단 List로 현재 설치된 package와 그 버전, 상태를 보도록 했다.


우선 pip install yolk 를 통해 yolk를 설치해야 하고, 파이썬 내에서 yolklib을 가져와서 사용한다.


++ 2016.11.18

- Yolk 라이브러리를 https://pypi.python.org/pypi/yolk3k 로 업데이트하면서 함수를 일부 변경하였습니다. 






 [ Source ]


- Main.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# -*- coding: utf-8 -*-
 
# Form implementation generated from reading ui file 'Main.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
 
from PyQt4 import QtCore, QtGui
 
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s
 
try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)
 
class Ui_QYolk(object):
    def setupUi(self, QYolk):
        QYolk.setObjectName(_fromUtf8("QYolk"))
        QYolk.resize(565321)
        self.centralwidget = QtGui.QWidget(QYolk)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.treeList = QtGui.QTreeWidget(self.centralwidget)
        self.treeList.setGeometry(QtCore.QRect(1010541271))
        self.treeList.setMaximumSize(QtCore.QSize(54116777215))
        self.treeList.setObjectName(_fromUtf8("treeList"))
        self.treeList.headerItem().setTextAlignment(0, QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter|QtCore.Qt.AlignCenter)
        self.treeList.headerItem().setBackground(0, QtGui.QColor(230230230))
        self.treeList.headerItem().setTextAlignment(1, QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter|QtCore.Qt.AlignCenter)
        self.treeList.headerItem().setBackground(1, QtGui.QColor(230230230))
        self.treeList.headerItem().setTextAlignment(2, QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter|QtCore.Qt.AlignCenter)
        self.treeList.headerItem().setBackground(2, QtGui.QColor(230230230))
        self.treeList.header().setCascadingSectionResizes(True)
        self.treeList.header().setHighlightSections(True)
        self.treeList.header().setSortIndicatorShown(False)
        QYolk.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(QYolk)
        self.menubar.setGeometry(QtCore.QRect(0056521))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        QYolk.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(QYolk)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        QYolk.setStatusBar(self.statusbar)
 
        self.retranslateUi(QYolk)
        QtCore.QMetaObject.connectSlotsByName(QYolk)
 
    def retranslateUi(self, QYolk):
        QYolk.setWindowTitle(_translate("QYolk""QYolk", None))
        self.treeList.headerItem().setText(0, _translate("QYolk""Package Name", None))
        self.treeList.headerItem().setText(1, _translate("QYolk""Version", None))
        self.treeList.headerItem().setText(2, _translate("QYolk""Status", None))
 
 
cs


- Start.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import sys
from PyQt4 import QtCore, QtGui
from Main import Ui_QYolk
from yolk import yolklib
 
class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_QYolk()
        self.ui.setupUi(self)
 
        # set Column Width
        self.ui.treeList.setColumnWidth(0200)
        self.ui.treeList.setColumnWidth(1200)
 
        packages = yolklib.get_distributions('all')
        for pkg in packages:
            newItem = QtGui.QTreeWidgetItem(self.ui.treeList)
            pk = str(pkg[0]).split(' ')
            if pkg[1]:
                status = 'Active'
            else:
                status = 'Not Active'
                newItem.setTextColor(0, QtGui.QColor(128128128))
                newItem.setTextColor(1, QtGui.QColor(128128128))
                newItem.setTextColor(2, QtGui.QColor(128128128))
                
            newItem.setText(0, pk[0])
            newItem.setText(1, pk[1])
            newItem.setText(2, status)
 
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = StartQT4()
    myapp.show()
    sys.exit(app.exec_())
cs


github : https://github.com/skyclad0x7b7/StudyPyQt4/tree/master/0x03.%20QYolk%20I

'Programming' 카테고리의 다른 글

[PyQt4] 0x05. Final Text Editor  (0) 2016.11.17
[PyQt4] 0x04. QYolk II  (0) 2016.11.16
[PyQt4] 0x02. Extended Text Editor  (0) 2016.11.15
[PyQt4] 0x01. PyQt4 설치, Simple text editor  (0) 2016.11.15
[Go] Defer, Panic, Recovery  (0) 2016.10.09
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,

기능 구현이 너무 쉽고 간단하다.

전에 만들었던 Simple Text Editor에 기능 몇가지를 추가했다.


- File Close 기능

- Save Button Disable 기능, textBrowser에 변화가 있을 경우 활성화됨

- 파일 변경 후 Save 없이 Close할 경우 메시지박스로 저장할 것인지 확인함




 [ Source ]


- Main.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# -*- coding: utf-8 -*-
 
# Form implementation generated from reading ui file 'Main.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
 
from PyQt4 import QtCore, QtGui
 
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s
 
try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)
 
class Ui_notepad(object):
    def setupUi(self, notepad):
        notepad.setObjectName(_fromUtf8("notepad"))
        notepad.resize(802625)
        self.centralwidget = QtGui.QWidget(notepad)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.textBrowser = QtGui.QTextBrowser(self.centralwidget)
        self.textBrowser.setGeometry(QtCore.QRect(1040781541))
        self.textBrowser.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByKeyboard|QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextBrowserInteraction|QtCore.Qt.TextEditable|QtCore.Qt.TextEditorInteraction|QtCore.Qt.TextSelectableByKeyboard|QtCore.Qt.TextSelectableByMouse)
        self.textBrowser.setObjectName(_fromUtf8("textBrowser"))
        self.button_open = QtGui.QPushButton(self.centralwidget)
        self.button_open.setGeometry(QtCore.QRect(10107523))
        self.button_open.setObjectName(_fromUtf8("button_open"))
        self.button_save = QtGui.QPushButton(self.centralwidget)
        self.button_save.setGeometry(QtCore.QRect(90107523))
        self.button_save.setCheckable(False)
        self.button_save.setAutoDefault(False)
        self.button_save.setDefault(False)
        self.button_save.setFlat(False)
        self.button_save.setObjectName(_fromUtf8("button_save"))
        self.button_close = QtGui.QPushButton(self.centralwidget)
        self.button_close.setGeometry(QtCore.QRect(710107523))
        self.button_close.setObjectName(_fromUtf8("button_close"))
        notepad.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(notepad)
        self.menubar.setGeometry(QtCore.QRect(0080221))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        notepad.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(notepad)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        notepad.setStatusBar(self.statusbar)
 
        self.retranslateUi(notepad)
        QtCore.QMetaObject.connectSlotsByName(notepad)
 
    def retranslateUi(self, notepad):
        notepad.setWindowTitle(_translate("notepad""Extended Text Editor", None))
        self.button_open.setText(_translate("notepad""Open", None))
        self.button_save.setText(_translate("notepad""Save", None))
        self.button_close.setText(_translate("notepad""Close", None))
 
 
cs


- Start.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import sys
import codecs
from os.path import isfile
from PyQt4 import QtCore, QtGui
from Main import Ui_notepad
 
class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_notepad()
        self.ui.setupUi(self)
        self.filename = ""
 
        QtCore.QObject.connect(self.ui.button_open, QtCore.SIGNAL("clicked()"), self.file_dialog)
        QtCore.QObject.connect(self.ui.button_save, QtCore.SIGNAL("clicked()"), self.file_save)
        QtCore.QObject.connect(self.ui.textBrowser, QtCore.SIGNAL("textChanged()"), self.enable_save)
        QtCore.QObject.connect(self.ui.button_close, QtCore.SIGNAL("clicked()"), self.file_close)
        self.initalize()
 
    def initalize(self):
        self.ui.textBrowser.setPlainText("")
        self.ui.button_save.setEnabled(False)
        self.setWindowTitle("Extended Text Editor")
 
    def file_dialog(self):
        fd = QtGui.QFileDialog(self)
        self.filename = fd.getOpenFileName()
        if isfile(self.filename):
            s = codecs.open(self.filename, 'r''utf-8').read()
            self.ui.textBrowser.setPlainText(s)
            self.setWindowTitle(self.filename)
            self.ui.button_save.setEnabled(False)
 
    def enable_save(self):
        self.ui.button_save.setEnabled(True)
 
    def file_save(self):
        if isfile(self.filename):
            file = codecs.open(self.filename, 'w''utf-8')
            file.write(unicode(self.ui.textBrowser.toPlainText()))
            file.close()
            self.ui.button_save.setEnabled(False)
 
    def file_close(self):
        if isfile(self.filename):
            # not saved
            if self.ui.button_save.isEnabled():
                message = QtGui.QMessageBox(self)
                message.setText('Would you like to save the file before closing?')
                message.setWindowTitle("Warning")
                message.setIcon(QtGui.QMessageBox.Question)
                message.addButton('Save', QtGui.QMessageBox.AcceptRole)
                message.addButton('Discard', QtGui.QMessageBox.DestructiveRole)
                message.addButton('Cancel', QtGui.QMessageBox.RejectRole)
                message.setDetailedText('Unsaved changes in file: ' + str(self.filename))
                message.exec_()
                response = message.clickedButton().text()
                if response == 'Save':
                    self.file_save()
                    self.ui.button_save.setEnabled(False)
                elif response == 'Discard':
                    self.initalize()
                else:
                    pass
            else:
                self.initalize()
                    
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = StartQT4()
    myapp.show()
    sys.exit(app.exec_())
cs


github : https://github.com/skyclad0x7b7/StudyPyQt4/tree/master/0x02.%20Extended%20Text%20Editor

'Programming' 카테고리의 다른 글

[PyQt4] 0x04. QYolk II  (0) 2016.11.16
[PyQt4] 0x03. QYolk I  (6) 2016.11.15
[PyQt4] 0x01. PyQt4 설치, Simple text editor  (0) 2016.11.15
[Go] Defer, Panic, Recovery  (0) 2016.10.09
[DLL Injection] DLL Injector  (0) 2016.10.05
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,